﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using VersionComparer.DataModel;
using VersionComparer.UI.ExtendedRichTextBox;
using System.IO;

namespace VersionComparer
{
    public partial class FileListInsertControl : UserControl
    {
        Dictionary<string, string[]> knownFolderFiles = new Dictionary<string, string[]>();
        public FileListInsertControl()
        {
            InitializeComponent();

            //txt1.ColorizeSyntax += txt1_ColorizeSyntax;
            //txt2.ColorizeSyntax += txt1_ColorizeSyntax;
            txt1.AutoCompleteGetSuggestions += txt1_AutoCompleteGetSuggestions;
            txt1.HideSelection = false;
            txt2.HideSelection = false;
        }

        void txt1_AutoCompleteGetSuggestions(object sender, AutoCompleteSuggestionEventArgs e)
        {
            if (String.IsNullOrEmpty(e.Text))
                return;
            if ( File.Exists ( e.Text ))
            {
                e.Suggestion = "";
                return;
                }
            try
            {
                string folder = Path.GetDirectoryName (e.Text );
                if (!String.IsNullOrEmpty(folder))
                {
                    string[] files;
                    if (!knownFolderFiles.TryGetValue(folder, out files))
                    {
                        List<string> newfiles = new List<string>();
                        newfiles.AddRange(Directory.GetFiles(folder));
                        newfiles.AddRange(Directory.GetDirectories(folder));
                        newfiles.Sort();
                        knownFolderFiles.Add(folder, files = newfiles.ToArray());
                    }
                    for (int i = files.Length - 1; i >= 0; i--)
                        if (files[i].StartsWith(e.Text, StringComparison.CurrentCultureIgnoreCase))
                        {
                            e.Suggestion = files[i].Substring ( e.Text.Length );
                            return;
                        }
                }
            }
            catch
            {
            }
        }

        private RichTextBoxColorInfoCollection GetLineColors(string lineText)
        {
            RichTextBoxColorInfoCollection colors = new RichTextBoxColorInfoCollection();
            if (File.Exists(lineText))
            {
                colors.Add(new RichTextBoxColorInfo(Color.Green));
                return colors;
            }
            if (Directory.Exists(lineText))
            {
                colors.Add(new RichTextBoxColorInfo(Color.Gray));
                return colors;
            }
            colors.Add(new RichTextBoxColorInfo(Color.Red));
            return colors;

        }

        void txt1_ColorizeSyntax(object sender, UI.ExtendedTreeView.ColorSyntaxEventArg e)
        {
            e.Colors = GetLineColors(e.Text);
        }

        protected override void OnLoad(EventArgs e)
        {
            if (FileList == null)
                FileList = new ItemNamePairList();
            txtName.Text = FileList.Name;
            txt1.Text = ListToText ( FileList.Items1);
            txt2.Text = ListToText ( FileList.Items2);
            base.OnLoad(e);
            
        }

        public void Close()
        {
            FileList.Set(txtName.Text, TextToList(txt1.Text), TextToList(txt2.Text));
        }
        public ItemNamePairList FileList
        {
            get;
            set;
        }

        private string ListToText(ItemId[] list)
        {
            if (list == null)
                return null;

            StringBuilder builder = new StringBuilder();
            foreach (ItemId file in list)
                builder.AppendLine(file.Name);
            return builder.ToString();
        }
        private string ListToText(string[] list)
        {
            if (list == null)
                return null;

            StringBuilder builder = new StringBuilder();
            foreach (string file in list)
                builder.AppendLine(file);
            return builder.ToString();
        }
        private string[] TextToList(string text)
        {
            if (text == null)
                return new string[0];
            return text.Split("\r\n;|".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);

        }
        private string Open(string text)
        {
            OpenFileDialog fd = new OpenFileDialog();
            fd.Multiselect = true;
            if ( fd.ShowDialog () == DialogResult.OK )
                return ListToText(fd.FileNames);
            return null;
        }

        private void btOpen1_Click(object sender, EventArgs e)
        {
            string newValue = Open(txt1.Text);
            if ( newValue != null )
                ReplaceTextInLine(txt1, CurrentSelectedLine(txt1), newValue);

        }

        private void btOpen2_Click(object sender, EventArgs e)
        {
            string newValue = Open(txt2.Text);
            if (newValue != null)
            {
                ReplaceTextInLine(txt2, CurrentSelectedLine(txt2), newValue);
            }

        }

        private string GetTextInLine(ExtendedRichTextBox txt, int line)
        {
            if (line < 0 || line >= txt.Lines.Length)
                return "";
            return txt.Lines[line];
            
        }
        private void txtName_TextChanged(object sender, EventArgs e)
        {
           
        }
        private int CurrentSelectedLine(ExtendedRichTextBox sourceTxt)
        {
            return sourceTxt.GetLineFromCharIndex(sourceTxt.GetFirstCharIndexOfCurrentLine());
        }

        private void ReplaceTextInLine(ExtendedRichTextBox txt, int line, string newText)
        {
            if (line >= 0 && line < txt.Lines.Length)
            {
                int selectionStart = txt.SelectionStart;
                StringBuilder builder = new StringBuilder();
                for (int i = 0; i < txt.Lines.Length; i++)
                    if (i == line)
                        builder.AppendLine(newText);
                    else
                        builder.AppendLine(txt.Lines[i]);
                txt.Text = builder.ToString().TrimEnd ("\r\n".ToCharArray ());
                txt.SelectionStart = selectionStart;
            }
        }
        private void SelectLine(ExtendedRichTextBox txt, int line)
        {
            int start = 0;
            txt.BeginUpdate();
            txt.Select(0, txt.Text.Length, Color.Black, Color.White);
            if (line >= 0 && line < txt.Lines.Length)
            {
                txt.Select(start = txt.GetFirstCharIndexFromLine(line), txt.Lines[line].Length, Color.Green, Color.White);
            }
            txt.SelectionStart = start;
            txt.SelectionLength = 0;
            txt.EndUpdate();
            
        }
        private void Synchronize(ExtendedRichTextBox sourceTxt, ExtendedRichTextBox destinationTxt)
        {
            
            SelectLine(destinationTxt, CurrentSelectedLine(sourceTxt));
            txt1Details.Text = GetTextInLine(txt1, CurrentSelectedLine(txt1));
            txt2Details.Text = GetTextInLine(txt2, CurrentSelectedLine(txt2));
        }
        private void txt1_Click(object sender, EventArgs e)
        {
            Synchronize(txt1, txt2);
        }

        private void txt1_KeyUp(object sender, KeyEventArgs e)
        {
            Synchronize(txt1, txt2);
        }

        private void txt2_Click(object sender, EventArgs e)
        {
            Synchronize(txt2, txt1);
        }

        private void txt2_KeyUp(object sender, KeyEventArgs e)
        {
            Synchronize(txt2, txt1);
        }

        private void txt2_Enter(object sender, EventArgs e)
        {
            txt2.Select(0, txt2.Text.Length, Color.Black, Color.White);
            txt2Details.Text = GetTextInLine(txt2, CurrentSelectedLine(txt2));
        }

        private void txt1_Enter(object sender, EventArgs e)
        {
            txt1.Select(0, txt2.Text.Length, Color.Black, Color.White);
            txt1Details.Text = GetTextInLine(txt1 , CurrentSelectedLine(txt1));
        }

        private void txt1_Leave(object sender, EventArgs e)
        {
            SelectLine(txt1, CurrentSelectedLine(txt1));
            //Synchronize(txt2, txt1);
        }

        private void txt2_Leave(object sender, EventArgs e)
        {
            SelectLine(txt2, CurrentSelectedLine(txt2));
        }

        private void textBox1_Leave(object sender, EventArgs e)
        {
        }

        private void textBox1_Enter(object sender, EventArgs e)
        {
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            if ( txt1Details.Focused )
                ReplaceTextInLine(txt1, CurrentSelectedLine(txt1), txt1Details.Text);
        }

        private void textBox2_TextChanged(object sender, EventArgs e)
        {
            if (txt2Details.Focused)
                ReplaceTextInLine(txt2, CurrentSelectedLine(txt2), txt2Details.Text);
            /*
            if (!txt2Details.ReadOnly)
            {
                ReplaceTextInLine(txt2, CurrentSelectedLine(txt2), txt2Details.Text);
            }
             * */
        }

        private void textBox2_Leave(object sender, EventArgs e)
        {
        }

        private void textBox2_Enter(object sender, EventArgs e)
        {
        }

        private void txt1_KeyPress(object sender, KeyPressEventArgs e)
        {

        }

        private void txt2_KeyPress(object sender, KeyPressEventArgs e)
        {

        }
    }
}
